import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class UdpEchoServer {
    // 注意：1.这个socket对象在操作系统内核中操作时，是当成文件的方式操作，把这个对象当成网卡的抽象
    private DatagramSocket socket = null;
    // 注意：2.服务器端需要手动指定一个端口，避免客户端找不到服务器
    public UdpEchoServer(int port) throws SocketException {
        this.socket = new DatagramSocket(port);
    }

    public void start() throws IOException {
        System.out.println("服务器启动!");
        while (true){
            // 1.给一个空的DatagramPacket,用于接收客户端发来的数据报
            DatagramPacket requestPacket = new DatagramPacket(new byte[4096],4096);
            socket.receive(requestPacket);   // 注意：如果receive没有接收到请求数据，那就会阻塞等待。

            // 注意1：为了便于处理，把DatagramPacket这个特殊的对象转化成字符串的形式,但是不能用toString,因为你无法为DatagramPacket类重写toString方法
            // 注意2：接收数据报时使用DatagramPacket的getLength方法获取数据报长度
            String request = new String(requestPacket.getData(),0,requestPacket.getLength());

            // 2.对请求内容进行业务处理(这里是回显服务器直接返回)
            String response = process(request);

            // 3.构造好响应的DatagramPacket，并把它发回客户端。
            // (注意1：这里也可以直接使用requestPacket.getSocketAddress()同时获取IP和端口，客户端的端口和ip是requestPacket自带的。
            //  注意2：第二个参数必须是字节数组长度response.getBytes().length,而不是字符串的长度
            //        使用String的getBytes().length方法获取数据报长度)
            DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),response.getBytes().length
                    ,requestPacket.getAddress(),requestPacket.getPort());
            socket.send(responsePacket);

            // 4.为了观察，打印一下客户端发来的的信息
            System.out.printf("[%s:%d] req:%s; resp:%s\n",requestPacket.getAddress(),requestPacket.getPort()
                                                          ,request, response);
        }
    }

    public String process(String request) {
        return request;
    }

    public static void main(String[] args) throws IOException {
        UdpEchoServer sever = new UdpEchoServer(9090);
        sever.start();
    }
}
